﻿namespace System.ServiceModel.DomainServices.Client
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.ComponentModel.DataAnnotations;

    public class InvokeOperation : OperationBase
    {
        private Action<InvokeOperation> _cancelAction;
        private Action<InvokeOperation> _completeAction;
        private string _operationName;
        private IDictionary<string, object> _parameters;
        private IEnumerable<ValidationResult> _validationErrors;

        internal InvokeOperation(string operationName, IDictionary<string, object> parameters, Action<InvokeOperation> completeAction, object userState, Action<InvokeOperation> cancelAction) : base(userState)
        {
            if (string.IsNullOrEmpty(operationName))
            {
                throw new ArgumentNullException("operationName");
            }
            this._operationName = operationName;
            this._parameters = parameters;
            this._cancelAction = cancelAction;
            this._completeAction = completeAction;
        }

        protected override void CancelCore()
        {
            this._cancelAction(this);
        }

        internal void Complete(IEnumerable<ValidationResult> validationErrors)
        {
            this._validationErrors = validationErrors;
            base.RaisePropertyChanged("ValidationErrors");
            DomainOperationException exception = new DomainOperationException(string.Format(CultureInfo.CurrentCulture, Resource.DomainContext_InvokeOperationFailed_Validation, new object[] { this.OperationName }), OperationErrorStatus.ValidationFailed);
            base.Complete((Exception) exception);
        }

        internal void Complete(Exception error)
        {
            if (typeof(DomainException).IsAssignableFrom(error.GetType()))
            {
                base.Complete(error);
            }
            else
            {
                string message = string.Format(CultureInfo.CurrentCulture, Resource.DomainContext_InvokeOperationFailed, new object[] { this.OperationName, error.Message });
                DomainOperationException exception = error as DomainOperationException;
                if (exception != null)
                {
                    error = new DomainOperationException(message, exception);
                }
                else
                {
                    error = new DomainOperationException(message, error);
                }
                base.Complete(error);
            }
        }

        internal void Complete(DomainClientResult result)
        {
            object obj2 = this.Value;
            base.Complete(result);
            if ((this.Result != null) && (this.Result.ReturnValue != obj2))
            {
                base.RaisePropertyChanged("Value");
            }
        }

        internal static InvokeOperation Create<TValue>(string operationName, IDictionary<string, object> parameters, Action<InvokeOperation> completeAction, object userState, Action<InvokeOperation> cancelAction)
        {
            Action<InvokeOperation<TValue>> action3 = null;
            Action<InvokeOperation<TValue>> action4 = null;
            Action<InvokeOperation<TValue>> action = null;
            Action<InvokeOperation<TValue>> action2 = null;
            if (completeAction != null)
            {
                if (action3 == null)
                {
                    action3 = delegate (InvokeOperation<TValue> arg) {
                        completeAction(arg);
                    };
                }
                action = action3;
            }
            if (cancelAction != null)
            {
                if (action4 == null)
                {
                    action4 = delegate (InvokeOperation<TValue> arg) {
                        cancelAction(arg);
                    };
                }
                action2 = action4;
            }
            return new InvokeOperation<TValue>(operationName, parameters, action, userState, action2);
        }

        protected override void InvokeCompleteAction()
        {
            if (this._completeAction != null)
            {
                this._completeAction(this);
            }
        }

        public string OperationName
        {
            get
            {
                return this._operationName;
            }
        }

        public IDictionary<string, object> Parameters
        {
            get
            {
                if (this._parameters == null)
                {
                    this._parameters = new Dictionary<string, object>();
                }
                return this._parameters;
            }
        }

        protected DomainClientResult Result
        {
            get
            {
                return (DomainClientResult) base.Result;
            }
        }

        protected override bool SupportsCancellation
        {
            get
            {
                return (this._cancelAction != null);
            }
        }

        public IEnumerable<ValidationResult> ValidationErrors
        {
            get
            {
                if (this.Result != null)
                {
                    return this.Result.ValidationErrors;
                }
                if (this._validationErrors == null)
                {
                    this._validationErrors = new ValidationResult[0];
                }
                return this._validationErrors;
            }
        }

        public object Value
        {
            get
            {
                if (this.Result == null)
                {
                    return null;
                }
                return this.Result.ReturnValue;
            }
        }
    }
}

